<template>
  <div class="page-container">
    <div class="page-content">
      <a-card>
        <!-- 搜索表单 -->
        <div class="search-form">
          <a-form layout="inline" :model="searchForm">
            <a-form-item label="关键词">
              <a-input
                v-model:value="searchForm.keyword"
                placeholder="请输入角色名称或标识"
                style="width: 200px"
                allow-clear
                @input="handleSearchInput"
              />
            </a-form-item>
            <a-form-item label="状态">
              <a-select
                v-model:value="searchForm.roleStatus"
                placeholder="请选择状态"
                style="width: 120px"
                allow-clear
              >
                <a-select-option value="enabled">启用</a-select-option>
                <a-select-option value="disabled">禁用</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="handleSearch">
                <SearchOutlined />
                查询
              </a-button>
              <a-button style="margin-left: 8px" @click="handleReset"> 重置 </a-button>
            </a-form-item>
          </a-form>
        </div>

        <!-- 操作按钮 -->
        <div class="table-operations">
          <PermissionButton permission="system:role:add">
            <a-button type="primary" @click="handleAdd">
              <PlusOutlined />
              新增角色
            </a-button>
          </PermissionButton>
        </div>

        <!-- 数据表格 -->
        <a-table
          :columns="columns"
          :data-source="dataSource"
          :loading="loading"
          :pagination="pagination"
          @change="handleTableChange"
          row-key="id"
        >
          <template #roleStatus="{ text }">
            <a-tag :color="text === 'enabled' ? 'green' : 'red'">
              {{ text === 'enabled' ? '启用' : '禁用' }}
            </a-tag>
          </template>
          <template #action="{ record }">
            <a-space>
              <PermissionButton permission="system:role:edit">
                <a-button type="link" size="small" @click="handleEdit(record)"> 编辑 </a-button>
              </PermissionButton>
              <PermissionButton permission="system:role:delete">
                <a-popconfirm
                  title="确定要删除这个角色吗？"
                  ok-text="确定"
                  cancel-text="取消"
                  @confirm="handleDelete(record)"
                >
                  <a-button type="link" size="small" danger>删除</a-button>
                </a-popconfirm>
              </PermissionButton>
            </a-space>
          </template>
        </a-table>
      </a-card>
    </div>

    <!-- 新增/编辑角色弹窗 -->
    <a-modal
      v-model:open="modalVisible"
      :title="modalType === 'add' ? '新增角色' : '编辑角色'"
      :width="800"
      :body-style="{ maxHeight: '70vh', overflow: 'auto' }"
      @ok="throttledModalOk"
      @cancel="handleModalCancel"
      :confirm-loading="modalLoading"
    >
      <a-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        :label-col="{ span: 4 }"
        :wrapper-col="{ span: 20 }"
      >
        <a-form-item label="角色名称" name="roleName">
          <a-input v-model:value="formData.roleName" placeholder="请输入角色名称" />
        </a-form-item>
        <a-form-item label="角色标识" name="roleKey">
          <a-input v-model:value="formData.roleKey" placeholder="请输入角色标识" />
        </a-form-item>
        <a-form-item label="角色状态" name="roleStatus">
          <a-radio-group v-model:value="formData.roleStatus">
            <a-radio value="enabled">启用</a-radio>
            <a-radio value="disabled">禁用</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item label="权限配置">
          <div class="permission-config">
            <!-- 权限展开控制 -->
            <div class="permission-controls">
              <span class="control-label">展开模式：</span>
              <a-radio-group v-model:value="permissionExpandMode" @change="handleExpandModeChange">
                <a-radio value="collapsed">不展开</a-radio>
                <a-radio value="expanded">展开权限及子项</a-radio>
              </a-radio-group>
            </div>

            <a-spin :spinning="permissionLoading">
              <div v-if="modalPermissionTreeData.length > 0" class="permission-tree-wrapper">
                <a-tree
                  v-model:checkedKeys="modalCheckedPermissions"
                  v-model:expandedKeys="modalExpandedKeys"
                  :tree-data="modalPermissionTreeData"
                  :field-names="{ title: 'permissionName', key: 'id', children: 'children' }"
                  checkable
                  check-strictly
                  :auto-expand-parent="false"
                  @check="handlePermissionCheck"
                >
                  <template #title="{ permissionName, type, permissionKey }">
                    <span :class="getPermissionClassName(type)">
                      {{ permissionName }}
                      <span class="permission-key">({{ permissionKey }})</span>
                    </span>
                  </template>
                </a-tree>
              </div>
              <div v-else class="no-permission-data">
                <a-empty description="暂无权限数据" />
              </div>
            </a-spin>
          </div>
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { SearchOutlined, PlusOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import type { FormInstance } from 'ant-design-vue'
import type { Role, RolePageParams, Permission, PermissionTree } from '@/types'
import { roleService } from '@/api/role'
import { permissionService } from '@/api/permission'
import PermissionButton from '@/components/PermissionButton.vue'
import { debounce, throttle } from '@/utils/debounce'

// 页面标题
const title = ref('角色管理')

// 页面描述
const description = ref('角色管理页面')

// 搜索表单
const searchForm = reactive({
  keyword: '',
  roleStatus: undefined as string | undefined,
})

// 表格数据
const dataSource = ref<Role[]>([])
const loading = ref(false)

// 分页配置
const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0,
  showSizeChanger: true,
  showQuickJumper: true,
  showTotal: (total: number) => `共 ${total} 条数据`,
})

// 表格列配置
const columns = [
  {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    width: 80,
  },
  {
    title: '角色名称',
    dataIndex: 'roleName',
    key: 'roleName',
  },
  {
    title: '角色标识',
    dataIndex: 'roleKey',
    key: 'roleKey',
  },
  {
    title: '状态',
    dataIndex: 'roleStatus',
    key: 'roleStatus',
    width: 100,
    slots: { customRender: 'roleStatus' },
  },
  {
    title: '创建时间',
    dataIndex: 'createdTime',
    key: 'createdTime',
    width: 180,
  },
  {
    title: '操作',
    key: 'action',
    width: 200,
    slots: { customRender: 'action' },
  },
]

// 新增/编辑相关
const modalVisible = ref(false)
const modalType = ref<'add' | 'edit'>('add')
const modalLoading = ref(false)
const formRef = ref<FormInstance>()

const formData = reactive<Partial<Role> & { permissionIds?: number[] }>({
  roleName: '',
  roleKey: '',
  roleStatus: 'enabled',
  permissionIds: [],
})

const formRules = {
  roleName: [
    { required: true, message: '请输入角色名称', trigger: 'blur' },
    { min: 2, max: 50, message: '角色名称长度在 2 到 50 个字符', trigger: 'blur' },
  ],
  roleKey: [
    { required: true, message: '请输入角色标识', trigger: 'blur' },
    {
      pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/,
      message: '角色标识必须以字母开头，只能包含字母、数字和下划线',
      trigger: 'blur',
    },
  ],
  roleStatus: [{ required: true, message: '请选择角色状态', trigger: 'change' }],
}

// 新增/编辑弹窗中的权限相关
const modalPermissionTreeData = ref<PermissionTree[]>([])
const modalCheckedPermissions = ref<number[]>([])
const modalExpandedKeys = ref<number[]>([])
const permissionLoading = ref(false)
const permissionExpandMode = ref<'collapsed' | 'expanded'>('collapsed')

// 获取数据
const fetchData = async () => {
  try {
    loading.value = true

    const params: RolePageParams = {
      page: pagination.current,
      pageSize: pagination.pageSize,
    }

    // 添加搜索条件
    if (searchForm.keyword) {
      params.roleName = searchForm.keyword
    }
    if (searchForm.roleStatus) {
      params.roleStatus = searchForm.roleStatus
    }

    const response = await roleService.getRolePage(params)
    dataSource.value = response.result
    pagination.total = response.total
  } catch (error) {
    console.error('获取角色数据失败:', error)
    message.error('获取角色数据失败')
  } finally {
    loading.value = false
  }
}

// 防抖搜索
const handleSearchInput = debounce(() => {
  handleSearch()
}, 500)

// 搜索
const handleSearch = () => {
  pagination.current = 1
  fetchData()
}

// 重置
const handleReset = () => {
  Object.assign(searchForm, {
    keyword: '',
    roleStatus: undefined,
  })
  pagination.current = 1
  fetchData()
}

// 新增
const handleAdd = async () => {
  modalType.value = 'add'
  Object.assign(formData, {
    id: undefined,
    roleName: '',
    roleKey: '',
    roleStatus: 'enabled',
    permissionIds: [],
  })

  // 重置权限选择和展开模式
  modalCheckedPermissions.value = []
  permissionExpandMode.value = 'collapsed'

  // 加载权限树数据
  await loadModalPermissionTree()

  modalVisible.value = true
}

// 编辑
const handleEdit = async (record: Role) => {
  modalType.value = 'edit'
  Object.assign(formData, {
    id: record.id,
    roleName: record.roleName,
    roleKey: record.roleKey,
    roleStatus: record.roleStatus,
    permissionIds: [],
  })

  // 重置展开模式为默认不展开
  permissionExpandMode.value = 'collapsed'

  // 加载权限树数据和角色已有权限
  await loadModalPermissionTree()
  await loadRolePermissions(record.id)

  modalVisible.value = true
}

// 加载权限树数据（用于新增/编辑弹窗）
const loadModalPermissionTree = async () => {
  try {
    permissionLoading.value = true
    const fullPermissionTree = await permissionService.getPermissionTree()
    modalPermissionTreeData.value = fullPermissionTree

    // 根据展开模式设置展开的节点
    if (permissionExpandMode.value === 'expanded') {
      modalExpandedKeys.value = extractAllPermissionIds(fullPermissionTree)
    } else {
      modalExpandedKeys.value = []
    }
  } catch (error) {
    console.error('获取权限树失败:', error)
    message.error('获取权限树失败')
  } finally {
    permissionLoading.value = false
  }
}

// 加载角色已有权限（用于编辑）
const loadRolePermissions = async (roleId: number) => {
  try {
    const roleDetail = await roleService.getRoleDetail(roleId)
    const assignedPermissionIds = roleDetail.authPermissionResponseVOS?.map((p) => p.id) || []

    // 直接使用已分配的权限ID，让权限树自己处理父子关系
    modalCheckedPermissions.value = assignedPermissionIds
    formData.permissionIds = assignedPermissionIds
  } catch (error) {
    console.error('获取角色权限失败:', error)
    message.error('获取角色权限失败')
  }
}

// 删除
const handleDelete = async (record: Role) => {
  try {
    await roleService.deleteRole(record.id)
    message.success('删除成功')
    fetchData()
  } catch (error) {
    console.error('删除角色失败:', error)
    message.error('删除角色失败')
  }
}

// 构建权限继承关系
const buildPermissionInheritance = (
  assignedIds: number[],
  fullTree: PermissionTree[]
): number[] => {
  // 实现权限继承逻辑：当父权限被选中时，自动选中所有子权限
  const inheritedIds = new Set(assignedIds)

  // 递归添加子权限
  const addChildrenPermissions = (permissions: PermissionTree[], parentId: number) => {
    permissions.forEach((permission) => {
      if (permission.parentId === parentId) {
        inheritedIds.add(permission.id)
        // 递归处理子权限
        if (permission.children && permission.children.length > 0) {
          addChildrenPermissions(permission.children, permission.id)
        }
      }
    })
  }

  // 扁平化权限树以便查找
  const flatPermissions: PermissionTree[] = []
  const flattenTree = (tree: PermissionTree[]) => {
    tree.forEach((item) => {
      flatPermissions.push(item)
      if (item.children && item.children.length > 0) {
        flattenTree(item.children)
      }
    })
  }
  flattenTree(fullTree)

  // 对每个已分配的权限，添加其所有子权限
  assignedIds.forEach((id) => {
    addChildrenPermissions(flatPermissions, id)
  })

  return Array.from(inheritedIds)
}

// 构建权限树（现在直接使用API返回的树形结构）
const buildPermissionTree = (permissions: Permission[]): PermissionTree[] => {
  // 如果已经有完整的权限树，直接返回
  if (modalPermissionTreeData.value.length > 0) {
    return modalPermissionTreeData.value
  }

  // 否则从扁平数据构建树形结构
  const tree: PermissionTree[] = []
  const map = new Map<number, PermissionTree>()

  // 创建所有节点的映射
  permissions.forEach((permission) => {
    map.set(permission.id, { ...permission, children: [] })
  })

  // 构建树形结构
  permissions.forEach((permission) => {
    if (permission.parentId === null || permission.parentId === 0) {
      tree.push(map.get(permission.id)!)
    } else {
      const parent = map.get(permission.parentId)
      if (parent) {
        parent.children = parent.children || []
        parent.children.push(map.get(permission.id)!)
      }
    }
  })

  return tree
}

// 提取所有权限ID用于展开
const extractAllPermissionIds = (permissions: PermissionTree[]): number[] => {
  const ids: number[] = []

  const extract = (perms: PermissionTree[]) => {
    perms.forEach((perm) => {
      ids.push(perm.id)
      // 检查是否有children属性且为数组
      if (perm.children && Array.isArray(perm.children)) {
        extract(perm.children)
      }
    })
  }

  extract(permissions)
  return ids
}

// 获取权限类型样式
const getPermissionClassName = (type: number) => {
  switch (type) {
    case 0:
      return 'permission-directory'
    case 1:
      return 'permission-menu'
    case 2:
      return 'permission-button'
    default:
      return ''
  }
}

// 表格分页、排序、筛选变化
const handleTableChange = (pag: any) => {
  pagination.current = pag.current
  pagination.pageSize = pag.pageSize
  fetchData()
}

// 弹窗确定
const handleModalOk = async () => {
  try {
    await formRef.value?.validate()
    modalLoading.value = true

    // 直接使用经过向上传播处理的权限列表
    const permissionIds = modalCheckedPermissions.value

    // 构建提交数据
    const submitData = {
      ...formData,
      permissionIds,
    }

    if (modalType.value === 'add') {
      await roleService.addRole(submitData)
      message.success('新增角色成功')
    } else {
      await roleService.updateRole(submitData)
      message.success('更新角色成功')
    }

    modalVisible.value = false
    fetchData()
  } catch (error) {
    console.error('保存角色失败:', error)
    message.error('保存角色失败')
  } finally {
    modalLoading.value = false
  }
}

// 弹窗取消
const handleModalCancel = () => {
  modalVisible.value = false
  formRef.value?.resetFields()

  // 清空权限相关数据
  modalPermissionTreeData.value = []
  modalCheckedPermissions.value = []
  modalExpandedKeys.value = []
  permissionExpandMode.value = 'collapsed'
  formData.permissionIds = []
}

// 节流处理按钮点击，防止重复提交
const throttledModalOk = throttle(handleModalOk, 300)

// 构建权限ID映射表，用于快速查找父子关系
const buildPermissionIdMap = (permissions: PermissionTree[]): Map<number, PermissionTree> => {
  const map = new Map<number, PermissionTree>()

  const addToMap = (perms: PermissionTree[]) => {
    perms.forEach((perm) => {
      map.set(perm.id, perm)
      if (perm.children && Array.isArray(perm.children)) {
        addToMap(perm.children)
      }
    })
  }

  addToMap(permissions)
  return map
}

// 向上递归添加父级权限
const addParentPermissions = (
  nodeId: number,
  checkedKeys: number[],
  permissionMap: Map<number, PermissionTree>
): number[] => {
  const result = new Set(checkedKeys)

  // 添加当前节点
  result.add(nodeId)

  // 递归向上添加所有父级权限
  const addParents = (id: number) => {
    const node = permissionMap.get(id)

    if (node && node.parentId && node.parentId !== 0 && node.parentId !== null) {
      result.add(node.parentId)
      addParents(node.parentId) // 递归向上
    }
  }

  addParents(nodeId)
  return Array.from(result)
}

// 检查是否还有其他子权限被选中
const hasSelectedChildren = (
  nodeId: number,
  checkedKeys: number[],
  permissionMap: Map<number, PermissionTree>
): boolean => {
  const node = permissionMap.get(nodeId)
  if (!node || !node.children || !Array.isArray(node.children)) {
    return false
  }

  // 检查直接子权限是否有被选中的
  for (const child of node.children) {
    if (checkedKeys.includes(child.id)) {
      return true
    }
    // 递归检查子权限的子权限
    if (hasSelectedChildren(child.id, checkedKeys, permissionMap)) {
      return true
    }
  }

  return false
}

// 智能移除权限和孤立的父级权限
const removePermissionAndCheckParents = (
  nodeId: number,
  checkedKeys: number[],
  permissionMap: Map<number, PermissionTree>
): number[] => {
  const result = new Set(checkedKeys)

  // 移除当前节点
  result.delete(nodeId)

  // 检查父级是否还有其他子节点被选中，如果没有则也移除
  const checkAndRemoveParents = (id: number) => {
    const node = permissionMap.get(id)
    if (node && node.parentId && node.parentId !== 0 && node.parentId !== null) {
      const parent = permissionMap.get(node.parentId)
      if (parent && parent.children) {
        // 检查父级的其他子节点是否还有被选中的
        const hasOtherSelectedChildren = parent.children.some(
          (child) => child.id !== id && result.has(child.id)
        )

        // 如果没有其他子节点被选中，且父级也在选中列表中，则移除父级
        if (!hasOtherSelectedChildren && result.has(node.parentId)) {
          result.delete(node.parentId)
          checkAndRemoveParents(node.parentId) // 递归检查上级
        }
      }
    }
  }

  checkAndRemoveParents(nodeId)
  return Array.from(result)
}

// 权限选择处理 - 支持向上传播
const handlePermissionCheck = (checkedKeys: any, info: any) => {
  // 获取用户实际选中的权限列表
  let userSelectedKeys: number[] = []
  if (Array.isArray(checkedKeys)) {
    userSelectedKeys = checkedKeys
  } else if (checkedKeys && checkedKeys.checked) {
    userSelectedKeys = checkedKeys.checked
  }

  // 构建权限映射表
  const permissionMap = buildPermissionIdMap(modalPermissionTreeData.value)

  let finalCheckedKeys: number[]

  // 如果有具体的节点操作信息（用户单击了某个权限）
  if (info && info.node) {
    const nodeId = info.node.id
    const isChecked = info.checked

    if (isChecked) {
      // 选中时：在当前权限基础上添加父级权限
      finalCheckedKeys = addParentPermissions(nodeId, userSelectedKeys, permissionMap)

      // 用户友好提示：如果自动选中了父级权限
      const addedParentCount = finalCheckedKeys.length - userSelectedKeys.length
      if (addedParentCount > 0) {
        message.info(`已自动选中 ${addedParentCount} 个上级目录权限，确保权限结构完整`)
      }
    } else {
      // 取消选中时：智能判断父级是否需要保留
      const originalLength = userSelectedKeys.length
      finalCheckedKeys = removePermissionAndCheckParents(nodeId, userSelectedKeys, permissionMap)

      // 用户友好提示：如果自动取消了父级权限
      const removedCount = originalLength - finalCheckedKeys.length
      if (removedCount > 1) {
        message.info(`已自动取消 ${removedCount - 1} 个上级目录权限`)
      }
    }
  } else {
    // 批量操作或初始化时，直接使用传入的权限列表
    finalCheckedKeys = userSelectedKeys
  }

  // 更新选中的权限列表
  modalCheckedPermissions.value = finalCheckedKeys
  formData.permissionIds = finalCheckedKeys
}

// 处理权限展开模式变化
const handleExpandModeChange = () => {
  if (permissionExpandMode.value === 'expanded') {
    // 展开所有节点
    modalExpandedKeys.value = extractAllPermissionIds(modalPermissionTreeData.value)
  } else {
    // 收起所有节点
    modalExpandedKeys.value = []
  }
}

// 组件挂载时获取数据
onMounted(() => {
  fetchData()
})
</script>

<style scoped lang="scss">
.page-container {
  padding: 24px;

  .page-header {
    margin-bottom: 24px;

    h1 {
      margin: 0 0 8px 0;
      font-size: 24px;
      font-weight: 600;
      color: #262626;
    }

    .page-description {
      margin: 0;
      color: #8c8c8c;
      font-size: 14px;
    }
  }

  .page-content {
    .search-form {
      margin-bottom: 16px;
      padding: 16px;
      background: #fafafa;
      border-radius: 6px;
    }

    .table-operations {
      margin-bottom: 16px;
    }
  }
}

.permission-config {
  .permission-controls {
    margin-bottom: 12px;
    padding: 8px 12px;
    background: #f5f5f5;
    border-radius: 4px;
    display: flex;
    align-items: center;

    .control-label {
      margin-right: 12px;
      color: #666;
      font-size: 14px;
      font-weight: 500;
    }
  }

  .permission-tree-wrapper {
    max-height: 250px;
    overflow-y: auto;
    border: 1px solid #d9d9d9;
    border-radius: 6px;
    padding: 12px;
    background: #fff;
  }

  .no-permission-data {
    height: 150px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #d9d9d9;
    border-radius: 6px;
    background: #fafafa;
  }

  .permission-key {
    color: #999;
    font-size: 12px;
    margin-left: 8px;
  }

  .permission-directory {
    color: #1890ff;
    font-weight: 500;
  }

  .permission-menu {
    color: #52c41a;
  }

  .permission-button {
    color: #fa8c16;
  }
}
</style> 